package com.example.bluetoothclicker.func

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.util.Log
import java.io.IOException
import java.util.UUID
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class BluetoothClient(
    private val device: BluetoothDevice,
    private val uuid: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"),
) {

    @Volatile
    private var socket: BluetoothSocket? = null
    private val sendExecutor: ExecutorService = Executors.newSingleThreadExecutor() // 独立发送线程池
    private val receiveExecutor: ExecutorService = Executors.newSingleThreadExecutor() // 独立接收线程池
    @Volatile
    private var isConnected = false
    @Volatile
    private var isReceivingMessages = false
    private var serverAddress: String? = null

    fun getServerAddress(): String? = serverAddress

    fun isConnectionActive(): Boolean = isConnected

    @Synchronized
    fun connectToServer(onConnected: (BluetoothSocket) -> Unit, onError: (Exception) -> Unit) {
        if (isConnected) {
            onError(Exception("已经连接到设备"))
            return
        }

        sendExecutor.execute {
            try {
                val tmpSocket = device.createRfcommSocketToServiceRecord(uuid)
                tmpSocket.connect()
                synchronized(this) {
                    socket = tmpSocket
                    isConnected = true
                    serverAddress = device.address
                }
                onConnected(tmpSocket)
            } catch (e: IOException) {
                e.printStackTrace()
                onError(IOException("连接错误: ${e.message}", e))
            }
        }
    }

    @Synchronized
    fun closeConnection() {
        if (!isConnected) return
        try {
            socket?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            synchronized(this) {
                socket = null
                isConnected = false
            }
        }
    }

    fun sendMessage(message: String, onStatusChanged: (String) -> Unit) {
        Log.d("BluetoothClient", "准备发送消息: $message")

        if (!isConnected || socket == null || !socket!!.isConnected) {
            val errorMsg = "无法发送消息: 当前没有活动连接或连接已关闭"
            Log.e("BluetoothClient", errorMsg)
            onStatusChanged(errorMsg)
            return
        }

        if (sendExecutor.isShutdown) {
            Log.e("BluetoothClient", "发送线程池已关闭，无法发送消息")
            onStatusChanged("发送线程池已关闭，无法发送消息")
            return
        }

        Log.d("BluetoothClient", "发送线程池运行正常，可以执行任务")

        sendExecutor.execute {
            try {
                synchronized(this) {
                    val outputStream = socket?.outputStream ?: throw IOException("输出流为null")
                    Log.d("BluetoothClient", "开始写入数据到输出流")
                    outputStream.write((message + "\n").toByteArray())
                    outputStream.flush()
                }
                Log.d("BluetoothClient", "发送消息成功: $message")
                onStatusChanged("消息发送成功: $message")
            } catch (e: IOException) {
                val errorMsg = "发送消息失败: ${e.message}"
                Log.e("BluetoothClient", errorMsg)
                e.printStackTrace()
                onStatusChanged(errorMsg)
            } finally {
                Log.d("BluetoothClient", "消息发送任务完成")
                onStatusChanged("消息发送任务完成")
            }
        }
    }

    /**
     * 启动消息接收
     * @param onMessageReceived 回调函数，当收到消息时触发
     */
    fun startReceiveMessages(onMessageReceived: (String) -> Unit) {
        if (isReceivingMessages) {
            Log.w("BluetoothClient", "消息接收已启动")
            return
        }

        isReceivingMessages = true // 启动接收标志

        if (receiveExecutor.isShutdown) {
            Log.e("BluetoothClient", "接收线程池已关闭，无法启动接收消息")
            return
        }

        receiveExecutor.execute {
            try {
                val inputStream = socket?.inputStream ?: throw IOException("输入流为空")
                val buffer = ByteArray(1024)
                while (isReceivingMessages) {
                    if (socket == null || !socket!!.isConnected) {
                        throw IOException("Socket已关闭，无法接收消息")
                    }
                    val bytes = inputStream.read(buffer)
                    if (bytes > 0) {
                        val message = String(buffer, 0, bytes).trim()
                        Log.d("BluetoothClient", "接收到消息: $message")
                        onMessageReceived(message)
                    }
                }
            } catch (e: IOException) {
                Log.e("BluetoothClient", "消息接收失败: ${e.message}")
                e.printStackTrace()
            } finally {
                Log.d("BluetoothClient", "消息接收已停止")
            }
        }
    }

    /**
     * 停止消息接收
     */
    fun stopMessageReceiving() {
        isReceivingMessages = false
    }

    fun releaseResources() {
        sendExecutor.shutdownNow()
        receiveExecutor.shutdownNow()
        closeConnection()
    }
}
